#include <vcl.h>
#pragma hdrstop

#include "CDBEditEuro.h"
#pragma link "CDBEdit"
#pragma package(smart_init)

#define EPAISSEUR 1
//---------------------------------------------------------------------------
// ValidCtrCheck est utilisé est utilisé pour être sûr que les composants créés n'ont
// aucune fonction virtuelle pure.
//

static inline void ValidCtrCheck(CDBEditEuro *)
{
    new CDBEditEuro(NULL);
}
//---------------------------------------------------------------------------
__fastcall CDBEditEuro::CDBEditEuro(TComponent* Owner)
    : CDBEdit(Owner)
{
    bFirstAff       = true;
    m_bVisuBouton   = true;
    
    if (ComponentState.Contains( csDesigning )) {
        newBouttonAff();
    }
}

//---------------------------------------------------------------------------
__fastcall CDBEditEuro::~CDBEditEuro ()
{
    if (!FormPopUp)     detruitPopUp();
    if (!BouttonAff)    detruitBouttonAff();
}

//---------------------------------------------------------------------------
namespace Cdbediteuro
{
    void __fastcall PACKAGE Register()
    {
         TComponentClass classes[1] = {__classid(CDBEditEuro)};
         RegisterComponents("EIC CtrlDB", classes, 0);
    }
}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::SetParent(TWinControl* AParent)
{
    CDBEdit::SetParent(AParent);
    if (BouttonAff) BouttonAff->Parent  = AParent;
//    if (FormPopUp)  FormPopUp->Parent   = AParent;
}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::SetVisuBouton( bool bVisu)
{
    m_bVisuBouton = bVisu;
    
    if (!BouttonAff && m_bVisuBouton)   newBouttonAff();
}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::newBouttonAff(void)
{
    //Boutton pour lancer l'affichage de la saisie en Francs
    BouttonAff              = new TSpeedButton(Parent);
    BouttonAff->Parent      = Parent;
    BouttonAff->Left        = Left + Width;
    BouttonAff->Top         = Top + 1;
    BouttonAff->OnClick     = BouttonAffClick;
    BouttonAff->Width       = 17;
    BouttonAff->NumGlyphs   = 2;
    BouttonAff->Glyph->LoadFromResourceName(( int)HInstance, "ARROW");
    BouttonAff->Visible     = true;
    BouttonAff->Height      = Height - 2;
}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::detruitBouttonAff(void)
{
    if (BouttonAff) {
        delete BouttonAff;
        BouttonAff = NULL;
    }
}

//---------------------------------------------------------------------------
//Fonction permettant de recuperer les changements de taille
//et les appliques à tous les éléments
void __fastcall CDBEditEuro::WMWindowPosChanged( TWMWindowPosChanged &Msg)
{
    CDBEdit::Dispatch( &Msg);

    if (BouttonAff) {
        BouttonAff->Left    = Left + Width;
        BouttonAff->Top     = Top + 1;
        BouttonAff->Height  = Height - 2;
    }
}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::WMSetFocus( TWMSetFocus &Msg)
{
    CDBEdit::Dispatch( &Msg);
    if (!BouttonAff && m_bVisuBouton)   newBouttonAff();
}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::WMKillFocus( TWMKillFocus &Msg)
{
    CDBEdit::Dispatch( &Msg);
    if (!FormPopUp) {
        detruitBouttonAff();
    } else {
        if (!FormPopUp->Visible) {
            detruitBouttonAff();
            detruitPopUp();
        }
    }

}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::WMChar( Messages::TWMChar& Msg)
{
   switch (Msg.CharCode) {
    case VK_SPACE :
        {
            if (m_bVisuBouton) {
                if (!BouttonAff) newBouttonAff();
                BouttonAffClick(BouttonAff);
            }
        }
        break;
    case VK_BACK :
        inherited::Dispatch( &Msg);
        break;
    case VK_RETURN :
        inherited::Dispatch( &Msg);
        break;
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   if((SelStart == 0) && (Font->Color == clRed))
                    Font->Color = clWindowText;
                inherited::Dispatch(&Msg);                    
               break;
    case 'F':
    case 'f':  {
                   if ((Text != "") && (m_TypeMonnaie == edbEuro)){
                       double dEuro = ConvFrToEu( StrToFloat(Text), true);
                       Text = FloatToStr(dEuro);
                       SelectAll();
                   } else {
                    MessageBeep( 0xFFFFFFFF);
                    Msg.Result = 0;
                   }
               }
               break;
    case 'E':
    case 'e':  {
                   if ((Text != "") && (m_TypeMonnaie == edbFranc)){
                       double dEuro = ConvFrToEu( StrToFloat(Text), false);
                       Text = FloatToStr(dEuro);
                       SelectAll();
                   } else {
                    MessageBeep( 0xFFFFFFFF);
                    Msg.Result = 0;
                   }
               }
               break;
    case ',':
    case '.': {
                    if (SelStart != 0) {
                            Msg.CharCode = DecimalSeparator;
                            inherited::Dispatch( &Msg);
                    }
                  }
                  break;
    case '-':  if( (SelStart == 0) || (Text.AnsiCompare( "0" ) != 0) ) {
    			   Font->Color = clRed;
                   inherited::Dispatch(&Msg);
               }
				break;
    default:   MessageBeep( 0xFFFFFFFF);
               Msg.Result = 0;
   }

}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::BouttonAffClick( TObject *pSender)
{
    if (!FormPopUp) newPopUp();

    //Ajoute le symbole Monétaire
    AnsiString asSymbole    = "";
    bool TypeMonnaie        = false;
    if (m_TypeMonnaie == edbEuro) {
        asSymbole = "F";
    } else {
        asSymbole = "€";
        TypeMonnaie        = true;
    }

    //Redimensionne la fenetre PopUp
    if ((Text == "") || (Text == "0")) {
        lAffFranc->Visible = false;
        FormPopUp->Height = Height;
    } else {
        lAffFranc->Visible = true;
        FormPopUp->Height = Height + lAffFranc->Height;
        AnsiString asText = FloatToStr(ConvFrToEu ( StrToFloat(Text), TypeMonnaie));
        lAffFranc->Caption = AddSeparMillier(asText)+ " " + asSymbole + " ";
    }

    PanelAff->Height        = FormPopUp->Height - (EPAISSEUR * 2);
    EditFranc->Height       = PanelBas->Height;
    lAffSymboleFr->Height   = PanelBas->Height;

    FormPopUp->Width        = Width + 17;
    PanelAff->Width         = FormPopUp->Width - (EPAISSEUR * 2); //Width - (EPAISSEUR * 2) + 17;
    lAffSymboleFr->Width    = 17;
    EditFranc->Width        = PanelAff->Width - lAffSymboleFr->Width;

    lAffSymboleFr->Left = EditFranc->Width;

    // Place la fenêtre au bonne endroit
    //TPoint *point = new TPoint();
    TPoint point;
    point.x = Left - 17;
    point.y = Top + Height;
    
    //point = RecupCoordForm(Parent, point);

    point   = Parent->ClientToScreen( point);
    if (( point.x + FormPopUp->Width) > Screen->Width) point.x = ( Screen->Width-FormPopUp->Width);
    FormPopUp->Left = point.x;
    FormPopUp->Top  = point.y;

    // Donne la focalisation à la forme et la met au premier plan
    FormPopUp->Visible = true;
    if (!bFirstAff)
        ShowPopUp();
    FormPopUp->SetFocus();
    FormPopUp->BringToFront();

    //Surtout ne pas modifier ce If
    if (bFirstAff) {
        bFirstAff = false;
        BouttonAffClick( BouttonAff );
    }

    EditFranc->Clear();

}

//---------------------------------------------------------------------------
/*
TWinControl* __fastcall CDBEditEuro::RecupFormParent(TWinControl *cParent)
{
    if (cParent->InheritsFrom(__classid(TCustomForm))) {
        return cParent;
    } else {
        RecupFormParent(cParent->Parent);
    }
}
*/
//---------------------------------------------------------------------------
/*
TPoint* __fastcall CDBEditEuro::RecupCoordForm(TWinControl *cParent, TPoint *point)
{
    if (cParent->InheritsFrom(__classid(TCustomForm))) {
        return point;
    } else {
        if (cParent->Left > 0)
            point->x += cParent->Left;
        if (cParent->Top > 0)
            point->y += cParent->Top;
        RecupCoordForm(cParent->Parent, point);
    }
}
*/
//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::newPopUp(void)
{
    /*TWinControl *ctrlParent = NULL;
    ctrlParent = RecupFormParent(Parent);*/

    //Forme d'affichage et de saisie des francs
    FormPopUp               = new TForm (Parent);
    FormPopUp->BorderStyle  = bsNone;
    FormPopUp->OnDeactivate = FormPopUpOnDeactivate;

    //Objet pour dessiner un rectangle autour de FormPopUp
    sRectTour               = new TShape (FormPopUp);
    sRectTour->Parent       = FormPopUp;
    sRectTour->Brush->Style = bsClear;
    sRectTour->Pen->Width   = EPAISSEUR;
    sRectTour->Align        = alClient;

    //Panel pour afficher en style combobox
    PanelAff                = new TPanel (FormPopUp);
    PanelAff->Parent        = FormPopUp;
    PanelAff->Left          = EPAISSEUR;
    PanelAff->Top           = EPAISSEUR;
    PanelAff->Color         = clWindow;
    PanelAff->BevelOuter    = bvNone;
    PanelAff->BevelInner    = bvNone;
    PanelAff->BorderStyle   = bsNone;

    //Affichage du montant en francs
    lAffFranc               = new TLabel (PanelAff);
    lAffFranc->Parent       = PanelAff;
    lAffFranc->Left         = 0;
    lAffFranc->Top          = 0;
    lAffFranc->Alignment    = taRightJustify;
    lAffFranc->Align        = alTop;
    lAffFranc->Height       = 13;
    lAffFranc->Color        = clBtnFace;

    //Panel pour afficher le bas de la form
    PanelBas                = new TPanel (PanelAff);
    PanelBas->Parent        = PanelAff;
    PanelBas->Align         = alClient;
    PanelBas->BevelOuter    = bvNone;
    PanelBas->BevelInner    = bvNone;
    PanelBas->BorderStyle   = bsNone;

    //Saisie du montant en francs
    EditFranc               = new CEditNum (PanelBas);
    EditFranc->Parent       = PanelBas;
    EditFranc->Left         = 0;
    EditFranc->Top          = 0;
    EditFranc->OnKeyDown    = EditFrancKeyDown;
    EditFranc->Font->Assign(Font);
    EditFranc->ColorNeg     = clRed;
    EditFranc->Color        = clInfoBk;
    EditFranc->Mask         = "############";
    EditFranc->Max          = 99999999999;
    EditFranc->MaxLength    = MaxLength;

    //Affichage du symbole des francs a cote de la saisie
    lAffSymboleFr               = new TLabel (PanelBas);
    lAffSymboleFr->Parent       = PanelBas;
    lAffSymboleFr->Width        = 17;
    lAffSymboleFr->Top          = 0;
    lAffSymboleFr->Caption      = "F";
    lAffSymboleFr->Alignment    = taCenter;
    lAffSymboleFr->Layout       = tlCenter;
    if (TypeMonnaie == edbEuro)
        lAffSymboleFr->Caption      = "F";
    else
        lAffSymboleFr->Caption      = "€";

}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::detruitPopUp(void)
{
    bFirstAff = true;

    if (sRectTour) {
        delete sRectTour;
        sRectTour = NULL;
    }
    if (lAffSymboleFr) {
        delete lAffSymboleFr;
        lAffSymboleFr = NULL;
    }
    if (EditFranc) {
        delete EditFranc;
        EditFranc = NULL;
    }
    if (PanelBas) {
        delete PanelBas;
        PanelBas = NULL;
    }
    if (lAffFranc) {
        delete lAffFranc;
        lAffFranc = NULL;
    }
    if (PanelAff) {
        delete PanelAff;
        PanelAff = NULL;
    }
    if (FormPopUp) {
        delete FormPopUp;
        FormPopUp = NULL;
    }
}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::FormPopUpOnDeactivate( TObject *pSender)
{
        HidePopUp();
        if (Text != "") {
            AnsiString asText = Text;
            if (StrToFloat(asText) >= 0) {
                Font->Color  = inherited::Font->Color;
            } else {
                Font->Color  = clRed;
            }
        }

        SetFocus();
        SelectAll();
}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::EditFrancKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
    if (Key == VK_ESCAPE) {
        //Sélectionne tout le texte
        if (Text.Length() != 0) {
            SelStart  = 0;
            SelLength = Text.Length();
        }
        FormPopUp->Visible = false;
    }

    if ((Key == VK_RETURN) || (Key == VK_TAB) || ((Key == VK_TAB) && Shift.Contains(ssShift))) {
        if (EditFranc->Valeur != I_NS) {
            bool TypeMonnaie        = false;
            bool bEditAuto          = false;

            if (m_TypeMonnaie == edbEuro) TypeMonnaie = true;

            if ((DataSource->State != dsEdit) && (DataSource->State != dsInsert)) {
                bEditAuto = true;
                DataSource->Edit();
            }

            Field->AsFloat = ConvFrToEu ( EditFranc->Valeur, TypeMonnaie);

            if (bEditAuto) {
                DataSource->DataSet->Post();
                Field->DataSet->Refresh();
            }

        } else {
            //Sélectionne tout le texte
            if (Text.Length() != 0) {
                SelStart  = 0;
                SelLength = Text.Length();
            }
        }
        FormPopUp->Visible = false;
    }
}

//---------------------------------------------------------------------------
double __fastcall CDBEditEuro::ConvFrToEu (double dVal, bool bFrancs)
{
    double dResult = 0;

    if (bFrancs) {
        dResult = dVal / 6.55957;
    } else {
        dResult = dVal * 6.55957;
    }

    dResult = (int)(floor(dResult + .5));

    return dResult;
}

//---------------------------------------------------------------------------
//Ajoute les Séparateurs de milliers
AnsiString __fastcall CDBEditEuro::AddSeparMillier( AnsiString asText)
{
    int         i;
    int         iCnt    = 0;
    AnsiString  asTemp  = asText;
    AnsiString  asFinal;
    AnsiString  asDec;

    if( asTemp.IsEmpty())
        return( AnsiString(""));

    i = asTemp.Length() - 1;

    // Ajoute les separateurs de milliers
    // Sauf pour les decimale
    /////////////////////////////////////
    bool bDec = true;
    while( i >= 0 ) {
        if( iCnt %3 == 0 && iCnt != 0 && !bDec) {
            if( !( i == 0 && asTemp.c_str()[ 0 ] == '-' ))
                asFinal.Insert( " ", 0 );
        }
        if (asTemp.c_str()[ i ] == DecimalSeparator)
            bDec = false;
        asFinal.Insert( asTemp.c_str()[ i ], 0 );
        iCnt ++;
        i --;
    }

    return( asFinal );
}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::ShowPopUp()
{
    if (FOnShowPopUp != NULL)   FOnShowPopUp(FormPopUp);
}

//---------------------------------------------------------------------------
void __fastcall CDBEditEuro::HidePopUp()
{
    if (FOnHidePopUp != NULL)   FOnHidePopUp(FormPopUp);
}

//---------------------------------------------------------------------------
